package dhost

import (
	_ "encoding/json"
	"errors"
	"gitee.com/hakwolf/dbmagic/golib/internal/sqldriver"
	"strconv"
	"strings"

	"gitee.com/hakwolf/dbmagic/golib/internal/models"
	"gitee.com/hakwolf/dbmagic/golib/internal/modules/logger"
	"gitee.com/hakwolf/dbmagic/golib/internal/modules/utils"
	"gitee.com/hakwolf/dbmagic/golib/internal/routers/base"
	"gopkg.in/macaron.v1"
)

const testConnectionCommand = "echo hello"
const testConnectionTimeout = 5

func GetMssqlDb(curHost models.DHost, dbname string, conMode int) sqldriver.Mssql {
	var dataSource string
	if curHost.Port != 0 {
		strInt64 := strconv.FormatInt(curHost.Port, 10)
		id16, _ := strconv.Atoi(strInt64)
		dataSource = curHost.Host + "," + strconv.Itoa(id16) //setting.Db.Host
	} else {
		dataSource = curHost.Host
	}
	return sqldriver.Mssql{
		DataSource: dataSource,
		Database:   dbname,
		// windwos: true 为windows身份验证，false 必须设置sa账号和密码
		Windows: curHost.Wmode == conMode,
		Sa: sqldriver.SA{
			User:   curHost.User,
			Passwd: curHost.Password,
		},
	}
}

type DHostForm struct {
	Id           int
	Name         string `binding:"Required;MaxSize(64)"`
	Host         string `binding:"Required;MaxSize(64)"`
	Port         int64  `binding:"Required;Range(1-65535)"`
	Remark       string
	Databasetype int
	User         string
	Password     string
	Database     string
	Charset      string
	Locate       string
	Version      string
	Sqlpath      string
	Local        int
	Wmode        int //认证模式  windows还是sql认证模式
}

// Index 主机列表
func Index(ctx *macaron.Context) string {
	hostModel := new(models.DHost)
	queryParams := parseQueryParams(ctx)
	total, err := hostModel.Total(queryParams)
	dhosts, err := hostModel.List(queryParams)
	if err != nil {
		logger.Error(err)
	}

	for _, v := range dhosts {
		v.Password = ""
	}

	jsonResp := utils.JsonResponse{}

	return jsonResp.Success(utils.SuccessContent, map[string]interface{}{
		"total": total,
		"data":  dhosts,
	})
}

// All 获取所有主机
func All(ctx *macaron.Context) string {
	hostModel := new(models.DHost)
	hostModel.PageSize = -1
	hosts, err := hostModel.List(models.CommonMap{})
	if err != nil {
		logger.Error(err)
	}

	jsonResp := utils.JsonResponse{}

	return jsonResp.Success(utils.SuccessContent, hosts)
}

// All 获取所有主机
func UIAll() []models.DHost {
	hostModel := new(models.DHost)
	hostModel.PageSize = -1
	hosts, err := hostModel.List(models.CommonMap{})
	if err != nil {
		logger.Error(err)
		return nil
	}
	return hosts
}

// Store 保存、修改主机信息
func UIStore(form models.DHost) (error, int) {
	hostModel := new(models.DHost)
	id := form.Id
	nameExist, err := hostModel.NameExists(form.Name, form.Id)
	var err2 error
	if err != nil {
		err2 = errors.New("操作失败")
		return err2, id //return json.CommonFailure("操作失败", err)
	}
	if nameExist {
		err2 = errors.New("实例名已存在")
		return err2, id //		return err, "主机别名已存在", id //return json.CommonFailure("主机别名已存在")
	}
	hostModel.Name = strings.TrimSpace(form.Name)
	//hostModel.Alias = strings.TrimSpace(form.Alias)
	hostModel.Port = form.Port
	hostModel.Remark = strings.TrimSpace(form.Remark)
	hostModel.Name = form.Name
	hostModel.Remark = form.Remark
	hostModel.User = form.User
	hostModel.Host = form.Host
	hostModel.Password = form.Password
	hostModel.Databasetype = form.Databasetype
	hostModel.Version = form.Version
	hostModel.Locate = form.Locate
	hostModel.Database = form.Database
	hostModel.Sqlpath = form.Sqlpath
	hostModel.Local = form.Local
	hostModel.Wmode = form.Wmode
	isCreate := false
	//oldHostModel := new(models.DHost)
	//err = oldHostModel.Find(int(id))
	//if err != nil {
	//	return err, "主机不存在", id   //return json.CommonFailure("主机不存在")
	//}

	if id > 0 {
		_, err = hostModel.UpdateBean(id)
	} else {
		isCreate = true
		id, err = hostModel.Create()
	}
	if err != nil {
		err2 = errors.New("保存失败！")
		return err2, id //return err, "保存失败", id //return json.CommonFailure("保存失败", err)
	}

	if !isCreate {
		//oldAddr := fmt.Sprintf("%s:%d", oldHostModel.Name, oldHostModel.Port)
		//newAddr := fmt.Sprintf("%s:%d", hostModel.Name, hostModel.Port)
		//if oldAddr != newAddr {
		//	grpcpool.Pool.Release(oldAddr)
		//}

		//taskModel := new(models.Task)
		//tasks, err := taskModel.ActiveListByHostId(id)
		//if err != nil {
		//	return err, "刷新任务主机信息失败", id
		//}
		//service.ServiceTask.BatchAdd(tasks)        //上出后再加
	}

	return nil, id //return nil, "保存成功", id
}

// Remove 删除主机
func UIRemove(id int) error {
	//id, err := strconv.Atoi(ctx.Params(":id"))
	//json := utils.JsonResponse{}
	//if err != nil {
	//	return json.CommonFailure("参数错误", err)
	//}
	//taskHostModel := new(models.TaskHost)
	//exist, err := taskHostModel.HostIdExist(int16(id))
	//if err != nil {
	//	return json.CommonFailure("操作失败", err)
	//}
	//if exist {
	//	return json.CommonFailure("有任务引用此主机，不能删除")
	//}
	//
	var err error
	if id <= 0 {
		err = errors.New("参数错误")
		return err
	}
	hostModel := new(models.DHost)
	err = hostModel.Find(int(id))
	if err != nil {
		err = errors.New("实例不存在")
		return err //return json.CommonFailure("主机不存在")
	}

	_, err = hostModel.Delete(id)
	if err != nil {
		err = errors.New("操作失败") //return json.CommonFailure("操作失败", err)
		return err
	}
	return nil
	//
	//addr := fmt.Sprintf("%s:%d", hostModel.Name, hostModel.Port)
	//grpcpool.Pool.Release(addr)
	//
	//return json.Success("操作成功", nil)

}

// Detail 主机详情
func Detail(ctx *macaron.Context) string {
	hostModel := new(models.DHost)
	id := ctx.ParamsInt(":id")
	err := hostModel.Find(id)
	jsonResp := utils.JsonResponse{}
	if err != nil || hostModel.Id == 0 {
		logger.Errorf("获取主机详情失败#主机id-%d", id)
		return jsonResp.Success(utils.SuccessContent, nil)
	}

	return jsonResp.Success(utils.SuccessContent, hostModel)
}

//// Error 表单验证错误处理
//func (f DHostForm) Error(ctx *macaron.Context, errs binding.Errors) {
//	if len(errs) == 0 {
//		return
//	}
//	json := utils.JsonResponse{}
//	content := json.CommonFailure("表单验证失败, 请检测输入")
//	ctx.Write([]byte(content))
//}

// 解析查询参数
func parseQueryParams(ctx *macaron.Context) models.CommonMap {
	var params = models.CommonMap{}
	params["Id"] = ctx.QueryInt("id")
	params["Name"] = ctx.QueryTrim("name")
	base.ParsePageAndPageSize(ctx, params)

	return params
}
